Skip to content

feat(plugins): project LlmResponse finish_reason to BigQuery analytics#5704

Open
roanny wants to merge 2 commits into
google:mainfrom
roanny:feat/llm-response-finish-reason
Open

feat(plugins): project LlmResponse finish_reason to BigQuery analytics#5704
roanny wants to merge 2 commits into
google:mainfrom
roanny:feat/llm-response-finish-reason

Conversation

@roanny
Copy link
Copy Markdown

@roanny roanny commented May 14, 2026

Summary

Projects finish_reason from LlmResponse to the attributes JSON column of LLM_RESPONSE events written to BigQuery by BigQueryAgentAnalyticsPlugin, and exposes it in the generated per-event-type SQL view.

Without this projection, classifying model failure modes (MAX_TOKENS, SAFETY, MALFORMED_FUNCTION_CALL, RECITATION, etc.) via SQL against the analytics table is impossible — the signal lives only in unstructured Cloud Logging output that is not joinable to the structured event stream.

Fixes #5644.

Changes

  • EventData gets a finish_reason: Optional[str] field.
  • after_model_callback reads llm_response.finish_reason.name and passes it through to EventData.
  • _enrich_attributes writes attrs["finish_reason"] when present (omitted entirely when None, so the JSON shape stays backwards-compatible for existing consumers).
  • _EVENT_VIEW_DEFS["LLM_RESPONSE"] projects JSON_VALUE(attributes, '$.finish_reason') AS finish_reason so it shows up as a typed column on the per-event-type view.
  • Schema-field description for the attributes column mentions the new key with example values.

Backwards compatibility

The new key is only added to the JSON when LlmResponse.finish_reason is not None, so events emitted before this change and events for streaming partials (where finish_reason is unset) remain unchanged. SQL consumers reading the existing documented fields are unaffected. New consumers can opt in via JSON_VALUE(attributes, '$.finish_reason') or via the finish_reason column exposed by the generated view.

Test plan

New unit tests (all passing locally; 229 passed, 5 skipped for the full plugin suite):

  • test_after_model_callback_projects_finish_reason — asserts MAX_TOKENS round-trips end-to-end into the BQ row's attributes.
  • test_after_model_callback_omits_finish_reason_when_absent — asserts the key is omitted when LlmResponse.finish_reason is None.
  • TestEnrichAttributes::test_finish_reason_included_when_set — direct _enrich_attributes coverage.
  • TestEnrichAttributes::test_finish_reason_omitted_when_none — direct _enrich_attributes coverage of the None branch.
  • Existing 229 tests in the plugin suite still pass (no regressions).

To run locally:

pytest tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py -k finish_reason -v

cc @sanketpatil06 @darshil3011

@google-cla
Copy link
Copy Markdown

google-cla Bot commented May 14, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Projects `finish_reason` from `LlmResponse` to the `attributes` JSON
column of `LLM_RESPONSE` events written to BigQuery by
`BigQueryAgentAnalyticsPlugin`, and exposes it as a typed column in the
generated per-event SQL view. Without this, classifying model failure
modes (MAX_TOKENS, SAFETY, MALFORMED_FUNCTION_CALL, RECITATION, etc.)
via SQL against the analytics table is impossible — the signal lives
only in unstructured Cloud Logging output that is not joinable to the
structured event stream.

Changes:
- `EventData` gets a `finish_reason: Optional[str]` field.
- `after_model_callback` reads `llm_response.finish_reason.name` via a
  defensive getattr (same back-compat pattern as `cache_metadata`,
  covering legacy response shapes).
- `_enrich_attributes` writes `attrs["finish_reason"]` only when set,
  keeping existing consumers and partial streaming events unaffected.
- `_EVENT_VIEW_DEFS["LLM_RESPONSE"]` projects
  `JSON_VALUE(attributes, '$.finish_reason')` as `finish_reason`.
- Schema-field description for `attributes` mentions the new key with
  example values.

Tests:
- `test_after_model_callback_projects_finish_reason` — MAX_TOKENS
  round-trips end-to-end into the BQ row's attributes.
- `test_after_model_callback_omits_finish_reason_when_absent` — key is
  omitted when `LlmResponse.finish_reason` is None.
- `TestEnrichAttributes::test_finish_reason_included_when_set` and
  `..._omitted_when_none` — direct `_enrich_attributes` coverage.
- Existing 229 plugin tests still pass; 5 skipped (pre-existing).

Fixes google#5644
@roanny roanny force-pushed the feat/llm-response-finish-reason branch from 5063422 to 2198289 Compare May 14, 2026 18:21
@roanny roanny changed the title feat(plugins): project LlmResponse finish_reason in BigQueryAgentAnalyticsPlugin LLM_RESPONSE events feat(plugins): project LlmResponse finish_reason to BigQuery analytics May 14, 2026
@roanny
Copy link
Copy Markdown
Author

roanny commented May 14, 2026

@googlebot I signed it!

@xuanyang15
Copy link
Copy Markdown
Collaborator

xuanyang15 commented May 18, 2026

@shobsi Could you please take a look, it is for #5644?

@rohityan rohityan requested review from shobsi and removed request for shobsi May 18, 2026 18:41
@rohityan rohityan added bq [Component] This issue is related to Big Query integration needs review [Status] The PR/issue is awaiting review from the maintainer labels May 18, 2026
@rohityan
Copy link
Copy Markdown
Collaborator

Hi @roanny , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Your PR has been received by the team and is currently under review. We will provide feedback as soon as we have an update to share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bq [Component] This issue is related to Big Query integration needs review [Status] The PR/issue is awaiting review from the maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: project finish_reason from LlmResponse to attributes in BigQueryAgentAnalyticsPlugin LLM_RESPONSE events

4 participants